#include "Bot.h"
#include <cstring>

using namespace std;

int* lastMove;

//constructor
Bot::Bot()
{

};

//plays a single game of Ants.
void Bot::playGame()
{
    //reads the game parameters and sets up
    cin >> state;
    state.setup();
    endTurn();
	
	//initialize
	lastMove = (int*)malloc(sizeof(int)*state.cols*state.rows);
	memset(lastMove, -1, sizeof(int)*state.cols*state.rows);

    //continues making moves while the game is not over
    while(cin >> state)
    {
        state.updateVisionInformation();
        makeMoves();
        endTurn();
    }
};

bool Bot::canMakeMove(Location loc){
	if(!state.grid[loc.row][loc.col].isWater && state.grid[loc.row][loc.col].ant == -1)
		return true;
	else return false;
}

//makes the bots moves for the turn
void Bot::makeMoves()
{
    state.bug << "turn " << state.turn << ":" << endl;
    state.bug << state << endl;

    //picks out moves for each ant
	
	//do BFS for each food to pick one ant to go towards
	bool moved[state.myAnts.size()];
	memset(moved, 0, sizeof(bool)*state.myAnts.size());
	Location list[state.rows*state.cols];
	bool visited[state.rows][state.cols];

	for (int food=0; food<(int)state.food.size(); food++) {
		memset(visited, 0, sizeof(bool)*state.rows*state.cols);

		Location start(state.food[food].row, state.food[food].col);
		int head = 0, tail = 0;
		list[head] = start;
		visited[start.row][start.col] = true;
		bool found = false;

		while (head <= tail){
			for (int dir = 0; dir < 4; dir ++){
				int xcol = (list[head].col+DIRECTIONS[dir][1] + state.cols) % state.cols, 
					xrow = (list[head].row+DIRECTIONS[dir][0] + state.rows) % state.rows;

				if (!state.grid[xrow][xcol].isWater && !visited[xrow][xcol]){
					visited[xrow][xcol] = true;
					int antNo = state.grid[xrow][xcol].ant;
					if (antNo != -1 && !moved[antNo]){   //found the closest unmoved ant	
						for(int d=0; d<TDIRECTIONS; d++){
							Location loc = state.getLocation(state.myAnts[antNo], d);
							if (visited[loc.row][loc.col] && state.grid[loc.row][loc.col].ant == -1
								&& d != (lastMove[antNo]+2) % 4){  //if it is closer to the food by moving in this direction
								state.makeMove(state.myAnts[antNo], d);
								lastMove[antNo] = d;
								moved[antNo] = true;
								found = true;
								break;
							}
						}
					}
					tail++;
					Location dummy(xrow, xcol);
					list[tail] = dummy;
				}
				if (found) break;
			}
			head++;
			if (found) break;
		}
			
	}

	//move the rest of the ants
    for(int ant=0; ant<(int)state.myAnts.size(); ant++){
		int increment = rand();
		if (!moved[ant]){
			if (lastMove[ant] != -1){
				Location loc = state.getLocation(state.myAnts[ant], lastMove[ant]); 
				loc.row = (loc.row + DIRECTIONS[lastMove[ant]][0] + state.rows) % state.rows;
				loc.col = (loc.col + DIRECTIONS[lastMove[ant]][1] + state.cols) % state.cols;
				if (canMakeMove(loc)) increment = lastMove[ant];
				else increment = lastMove[ant] + 1;
			}


			for(int d=increment; d<4+increment; d++){
				Location loc = state.getLocation(state.myAnts[ant], d%4);
				if (canMakeMove(loc)){
					state.makeMove(state.myAnts[ant], d%4);
					lastMove[ant] = d%4;
					break;
				}
			}

		}
	}

    state.bug << "time taken: " << state.timer.getTime() << "ms" << endl << endl;
};

//finishes the turn
void Bot::endTurn()
{
    if(state.turn > 0)
        state.reset();
    state.turn++;

    cout << "go" << endl;
};
